﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Xml;
using BDSim;


namespace DiagramDesigner
{
    /// <summary>
    /// 设计器画布
    /// </summary>
    public partial class DesignerCanvas : Canvas
    {
        #region ///add by lijing 2015.03.30
      
        public delegate void WavViewBntEnable(string modeType);//XYF  波浪等级按钮可用
        public WavViewBntEnable DlgWavViewBntEnable;

        public delegate void DisplayPropertyDelegate(Guid uid);
        public DisplayPropertyDelegate DlgDisplayProperty;
        public delegate void AddTrackModelDelegate(BaseTrackModel trackModel);
        public AddTrackModelDelegate DlgAddTrackModel;
        public delegate void DeleteTrackModelDelegate(Guid uid);
        public DeleteTrackModelDelegate DlgDeleteTrackModel;
        #endregion

        private Point? rubberbandSelectionStartPoint = null;

        private SelectionService selectionService;
        internal SelectionService SelectionService
        {
            get
            {
                if (selectionService == null)
                    selectionService = new SelectionService(this);

                return selectionService;
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Source == this)
            {
                // in case that this click is the start of a 
                // drag operation we cache the start point
                this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));

                // if you click directly on the canvas all 
                // selected items are 'de-selected'
                SelectionService.ClearSelection();
                Focus();
                e.Handled = true;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // if mouse button is not pressed we have no drag operation, ...
            if (e.LeftButton != MouseButtonState.Pressed)
                this.rubberbandSelectionStartPoint = null;

            // ... but if mouse button is pressed and start
            // point value is set we do have one
            if (this.rubberbandSelectionStartPoint.HasValue)
            {
                // create rubberband adorner
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
                if (adornerLayer != null)
                {
                    RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
                    if (adorner != null)
                    {
                        adornerLayer.Add(adorner);
                    }
                }
            }
            e.Handled = true;
        }

        protected override void OnDrop(DragEventArgs e)
        {
            base.OnDrop(e);
            DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
            if (dragObject != null && !String.IsNullOrEmpty(dragObject.Xaml))
            {
                DesignerItem newItem = null;
                Object dragContect = XamlReader.Load(XmlReader.Create(new StringReader(dragObject.Xaml)));

                if (dragContect != null )
                {
                    Object content = (dragContect as StackPanel).Children[0];
                    (dragContect as StackPanel).Children.Clear();
                    newItem = new DesignerItem() 
                    { 
                        ToolTip = (content as Image).ToolTip, 
                        Tag = (content as Image).Tag, 
                        Uid = (content as Image).Uid,
                        DlgDisplayProperty = SelectNode_MouseLeftDown 
                    };

                    #region ///add by [lijing] 2015.06.29
                    content = AddTrackDataModel(newItem, content);
                    #endregion

                    #region ///add by [lijing] 2015.04.29  如果已具备开始或结束模型，则不能再添加开始或结束模型
                    if (content!=null && (content as Image).Uid == "Start")
                    {
                        foreach (var item in this.Children)
                        {
                            if ((item is DesignerItem) && (item as DesignerItem).Uid == "Start")
                            {
                                content = null;
                                MessageBox.Show("已添加了一个“起始设定”轨迹模型，不能再添加！");
                                break;
                            }
                        }
                    }

                    //if (content != null && (content as Image).Uid == "Stop")
                    //{
                    //    foreach (var item in this.Children)
                    //    {
                    //        if ((item is DesignerItem) && (item as DesignerItem).Uid == "Stop")
                    //        {
                    //            content = null;
                    //            MessageBox.Show("已添加了一个“停止运动”轨迹模型，不能再添加！");
                    //            break;
                    //        }
                    //    }
                    //}
                    
                    #endregion
                    if (content == null)
                    {
                        return;
                    }
                    newItem.Content = content;


                    Point position = e.GetPosition(this);

                    if (dragObject.DesiredSize.HasValue)
                    {
                        //Size desiredSize = dragObject.DesiredSize.Value;
                        newItem.Width = 60;
                        newItem.Height = 60;

                        DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X - newItem.Width / 2));
                        DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y - newItem.Height / 2));
                    }
                    else
                    {
                        DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X));
                        DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y));
                    }

                    Canvas.SetZIndex(newItem, this.Children.Count);
                    this.Children.Add(newItem);
                    SetConnectorDecoratorTemplate(newItem);

                    //update selection
                    this.SelectionService.SelectItem(newItem);
                    newItem.Focus();
                }
                e.Handled = true;
            }
        }
        #region ///add by [lijing] 2015.06.29

        private Object AddTrackDataModel(DesignerItem newItem, Object content)
        {
            if (content != null)
            {
                BaseTrackModel Track = new BaseTrackModel();
                //将波浪等级按钮功能显示//xyf
                //DlgWavViewBntEnable((content as Image).Tag.ToString());
              
                switch ((content as Image).Tag.ToString())
                {
                    case "CarTrack":
                        if (this.Children.Count == 0 || (this.Children[0] as DesignerItem).Tag.ToString() == "CarTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("只能添加已有类型轨迹模型！");
                            content = null;
                        }
                        break;
                    case "AircraftTrack":
                        if (this.Children.Count == 0 || (this.Children[0] as DesignerItem).Tag.ToString() == "AircraftTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("只能添加已有类型轨迹模型！");
                            content = null;
                        }
                        break;
                    case "BoatTrack":
                        if (this.Children.Count == 0 || (this.Children[0] as DesignerItem).Tag.ToString() == "BoatTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("只能添加已有类型轨迹模型！");
                            content = null;
                        }
                        break;
                    case "CircleTrack":
                        if (this.Children.Count == 0 && (content as Image).Name == "CircleRun")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("不能再添加轨迹模型！");
                            content = null;
                        }
                        break;
                    case "BigCircleTrack":
                        if (this.Children.Count == 0 && (content as Image).Name == "BigCircleRun")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("不能再添加轨迹模型！");
                            content = null;
                        }
                        break;
                    case "InterCirTrack":
                        if (this.Children.Count == 0 && (content as Image).Name == "InterCirTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("不能再添加轨迹模型！");
                            content = null;
                        }
                        break;
                    case "InterLineSinTrack":
                        if (this.Children.Count == 0 && (content as Image).Name == "InterLineSinTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("不能再添加轨迹模型！");
                            content = null;
                        }
                        break;
                    case "InterLineTrack":
                        if (this.Children.Count == 0 && (content as Image).Name == "InterLineTrack")
                        {
                            Track = GetTrack((content as Image).Name);
                            Track.UID = newItem.ID.ToString();
                            if (DlgAddTrackModel != null)
                            {
                                DlgAddTrackModel(Track);
                            }
                        }
                        else
                        {
                            MessageBox.Show("不能再添加轨迹模型！");
                            content = null;
                        }
                        break;
                    default:
                        break;
                }
            }
            return content;
        }

        BaseTrackModel GetTrack(string trackType)
        {
            BaseTrackModel track = new BaseTrackModel();
            switch (trackType)
            {
                #region ///添加汽车轨迹模型
                case "CarStartSetting":
                    track = new CarStartSetting();
                    break;
                case "CarSteadyVelocityLine":
                    track = new CarSteadyVelocityLine();
                    break;
                case "CarAccelerateLine":
                    track = new CarAccelerateLine();
                    break;
                case "CarSteadyVelSwerve":
                    track = new CarSteadyVelSwerve();
                    break;
                case "CarClimbRun":
                    track = new CarClimbRun();
                    break;
                case "CarDotRun":
                    track = new CarDotRun();
                    break;
                case "CarStopRun":
                    track = new CarStopRun();
                    break;
                #endregion
                #region ///添加飞机轨迹模型
                case "AircraftStartSetting":
                    track = new AircraftStartSetting();
                    break;
                case "AircraftSteadyVelLine":
                    track = new AircraftSteadyVelLine();
                    break;
                case "AircraftAccelerateLine":
                    track = new AircraftAccelerateLine();
                    break;
                case "AircraftClimbRun":
                    track = new AircraftClimbRun();
                    break;
                case "AircraftSteadyVelSwerve":
                    track = new AircraftSteadyVelSwerve();
                    break;
                case "AircraftAcceSwerve":
                    track = new AircraftAcceSwerve();
                    break;
                case "AircraftPointRun":
                    track = new AircraftPointRun();
                    break;
                case "AircraftCombRun":
                    track = new AircraftCombRun();
                    break;
                case "AircraftStopRun":
                    track = new AircraftStopRun();
                    break;
                case "AircraftLinePitch":
                    track = new AircraftLinePitch();
                    break;
                case "AircraftLineLandRoll":
                    track = new AircraftLineLandRoll();
                    break;
                case "AircraftLineNav":
                    track = new AircraftLineNav();
                    break;
                #endregion
                #region ///添加轮船轨迹模型
                case "BoatStartSetting":
                    track = new BoatStartSetting();
                    break;
                case "BoatSteadyVelocityLine":
                    track = new BoatSteadyVelocityLine();
                    break;
                case "BoatAccelerateLine":
                    track = new BoatAccelerateLine();
                    break;
                case "BoatSteadyVelSwerve":
                    track = new BoatSteadyVelSwerve();
                    break;
                case "BoatPointRun":
                    track = new BoatPointRun();
                    break;
                case "BoatStopRun":
                    track = new BoatStopRun();
                    break;
                #endregion
                #region ///添加特殊轨迹模型
                case "CircleRun":
                    track = new CircleRun();
                    break;
                case "BigCircleRun":
                    track = new BigCircleRun();
                    break;
                case "InterCirTrack":
                    track = new InterCirTrack();
                    break;
                case "InterLineSinTrack":
                    track = new InterLineSinTrack();
                    break;
                case "InterLineTrack":
                    track = new InterLineTrack();
                    break;
                #endregion
                default:
                    break;
            }
            return track;
        }

        #endregion
        public void DragInEvent(object control)
        {
            //string XamlString = XamlWriter.Save(control);
            
            //Object content = XamlReader.Load(XmlReader.Create(new StringReader(XamlString)));
            //#region //add by [lijing] 2015.04.01
            //if (DlgAddDesignerItem != null)
            //{
            //    DlgAddDesignerItem(ref content);
            //}
            
            //#endregion
            //if (content != null)
            //{
            //    DesignerItem newItem = null;
            //    newItem = new DesignerItem() { ToolTip = (content as Image).Uid, DlgDisplayProperty = SelectNode_MouseLeftDown };
            //    newItem.Height = 45;
            //    newItem.Width = 45;
            //    #region ///add by [lijing] 2015.04.02
            //    switch ((content as Image).Tag.ToString())
            //    {
            //        //case "Satellite":
            //        //    newItem.Tag = ModelType.Satellite;
            //        //    break;
            //        //case "MasterStation":
            //        //    newItem.Tag = ModelType.MasterStation;
            //        //    break;
            //        //case "InjectionStation":
            //        //    newItem.Tag = ModelType.InjectionStation;
            //        //    break;
            //        //case "MonitorStation":
            //        //    newItem.Tag = ModelType.MonitorStation;
            //        //    break;
            //        //case "KaManageStation":
            //        //    newItem.Tag = ModelType.KaManageStation;
            //        //    break;
            //        //case "ManageCenterStation":
            //        //    newItem.Tag = ModelType.ManageCenterStation;
            //        //    break;
            //        //case "UserDevice":
            //        //    newItem.Tag = ModelType.UserDevice;
            //        //    break;
            //        //default:
            //        //    break;
            //    }
            //    #endregion

            //    newItem.Content = content;


            //    NodePosition.X += 45;
            //    NodePosition.Y += 45;

            //    DesignerCanvas.SetLeft(newItem, Math.Max(0, NodePosition.X));
            //    DesignerCanvas.SetTop(newItem, Math.Max(0, NodePosition.Y));
            //    Canvas.SetZIndex(newItem, this.Children.Count);
            //    this.Children.Add(newItem);
            //    SetConnectorDecoratorTemplate(newItem);

            //    //update selection
            //    this.SelectionService.SelectItem(newItem);
            //    newItem.Focus();
            //}
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Size size = new Size();

            foreach (UIElement element in this.InternalChildren)
            {
                double left = Canvas.GetLeft(element);
                double top = Canvas.GetTop(element);
                left = double.IsNaN(left) ? 0 : left;
                top = double.IsNaN(top) ? 0 : top;

                //measure desired size for each child
                element.Measure(constraint);

                Size desiredSize = element.DesiredSize;
                if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
                {
                    size.Width = Math.Max(size.Width, left + desiredSize.Width);
                    size.Height = Math.Max(size.Height, top + desiredSize.Height);
                }
            }
            // add margin 
            size.Width += 10;
            size.Height += 10;
            return size;
        }

        private void SetConnectorDecoratorTemplate(DesignerItem item)
        {
            if (item.ApplyTemplate() && item.Content is UIElement)
            {
                ControlTemplate template = DesignerItem.GetConnectorDecoratorTemplate(item.Content as UIElement);
                Control decorator = item.Template.FindName("PART_ConnectorDecorator", item) as Control;
                if (decorator != null && template != null)
                    decorator.Template = template;
            }
        }
        
        /// <summary>
        /// 左键点击节点时，显示节点属性
        /// </summary>
        /// <param name="SenderType">节点类型</param>
        /// <param name="NodeName">节点名称</param>
        public void SelectNode_MouseLeftDown(Guid uid)
        {
            this.DlgDisplayProperty(uid);
        }
    }
}
